package calao;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServlet;

import static calao.util.Logger.DEBUG;
import calao.util.Logger;

public abstract class WorkspaceServlet 
extends HttpServlet 
{

	final static int DEFAULT_SESSION_IDLE_TIMEOUT = 3600;
	
	final static char PATH_SEPARATOR = ';';
	
	private Server server;
	
	final static ThreadLocal<WebRequest> threadLocalRequest = 
		new ThreadLocal<WebRequest>();
			
	public void doGet(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException 
	{
		if (request.getSession().isNew()) {
			request.getSession().setMaxInactiveInterval(DEFAULT_SESSION_IDLE_TIMEOUT);
		}
		// parse URI for workspace name and workspace resource path
		String uri = request.getRequestURI();
		debug("Serving URI: %s", uri);
		int sepPos = uri.indexOf(PATH_SEPARATOR);
		if (sepPos==-1) {
			String toURL = uri;
			if (!toURL.endsWith("/")) toURL += '/';
			toURL += ";/";
			response.sendRedirect(toURL);
			debug("Redirected to %s", toURL);
		}
		else {
			String wsPath = uri.substring(0, sepPos);
			if (!Workspace.isValidPath(wsPath)) {
				response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			}
			else {
				String resourcePath = uri.substring(sepPos+1);
				// delegate processing to implementation
				WebRequest wrequest = new WebRequest(getServer(), 
						wsPath, resourcePath, 
						request, response); 
				try {
					threadLocalRequest.set(wrequest);
					debug("Processing request {id=%d, ws=%s, resource='%s', locale=%s}", 
							wrequest.id, wsPath, resourcePath, request.getLocale());
					process(wrequest);
				}
				finally {
					threadLocalRequest.set(null);
					wrequest.processed();
					debug("Request %d processed in %dms", wrequest.id, 
							wrequest.getProcessingTime());
				}
			}
		}
	}
		
	public void doPost(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException 
	{
		doGet(request, response);
	}

	abstract public void process(WebRequest request)
	throws ServletException, IOException;
	
	/** Gets the containing server.
	 */
	protected final Server getServer()
	{
		if (server==null) {
			server = (Server)getServletContext().getAttribute("calao.server");
		}
		return server;
	}
	
	static WebRequest getThreadLocalRequest()
	{
		return threadLocalRequest.get();
	}
	
	void debug(String msg, Object... args) 
	{
		Logger.log(DEBUG, msg, args);
	}
	
}
